/*********************************************************************\
*
*                  (c) lkc
*                  All Rights Reserved. lkc Confidential
*
\*********************************************************************/
/*********************************************************************\
*   Title                      :
*
*   Module Description         :
*
*   Author                     : lkc
*
*   Created                    : 2017-7-24
*
\*********************************************************************/
//#include<iostream>

#include "Gpio.h"
#include "UtilityTH.h"

#define SYSFS_GPIO "/sys/class/gpio"
#define SYSFS_GPIO_EXPORT SYSFS_GPIO"/export"
#define SYSFS_GPIO_UNEXPORT SYSFS_GPIO"/unexport"


Gpio::Gpio(int pin)
:m_pin(pin)
{
    DebugPrintf("Constructors io%d\n",static_cast<int>(m_pin));
    ExportIo();
}

void Gpio::ExportIo()
{
//    ostringstream s;
//    m_valueFileStr += fileName;
//    std::cout<<m_valueFileStr<<std::endl;
    char fileName[50];
    sprintf(fileName,SYSFS_GPIO"/gpio%d/value",static_cast<int>(m_pin));
    FILE *fp = fopen(fileName,"r");
    if(fp != nullptr)
    {
        DebugPrintf("%s exists, so io%d has been exported\n",fileName,static_cast<int>(m_pin));
        fclose(fp);
        return;
    }
    DebugPrintf("%s does not exist and io%d will be exported\n",fileName,static_cast<int>(m_pin));
    char pinIndex[10];
    sprintf(pinIndex,"%d",static_cast<int>(m_pin));
    MyWrite(SYSFS_GPIO_EXPORT,"w",pinIndex);
    DebugPrintf("export io%d\n",static_cast<int>(m_pin));
}

void Gpio::UnexportIo()
{
    char pinIndex[10];
    sprintf(pinIndex,"%d",static_cast<int>(m_pin));
    MyWrite(SYSFS_GPIO_UNEXPORT,"w",pinIndex);
    DebugPrintf("unexport io%d\n",static_cast<int>(m_pin));
}

void Gpio::SetDirection(const Dir direction)
{
    m_direction = direction;
    char fileName[50];
    sprintf(fileName,SYSFS_GPIO"/gpio%d/direction",static_cast<int>(m_pin));
    if(m_direction == Dir::IN)
    {
        DebugPrintf("io%d set direction in\n",static_cast<int>(m_pin));
        MyWrite(fileName,"w","in");
    }
    else
    {
        DebugPrintf("io%d set direction out\n",static_cast<int>(m_pin));
        MyWrite(fileName,"w","out");
    }
}

void Gpio::Write(const IoValue value) const
{
    if(m_direction!=Dir::OUT)
    {
        DebugPrintf("write forbidden\n");
        return;
    }
    DebugPrintf("io%d write %d\n",static_cast<int>(m_pin),static_cast<int>(value));
    char fileName[50];
    sprintf(fileName,SYSFS_GPIO"/gpio%d/value",static_cast<int>(m_pin));
    char content[10];
    sprintf(content,"%d",static_cast<int>(value));
    MyWrite(fileName,"w",content);
}

int Gpio::Read() const
{
    FILE * fp;
    int read_len;
    unsigned char file_buffer[5];
    memset(file_buffer,-1,5);
    char fileName[50];
    sprintf(fileName,SYSFS_GPIO"/gpio%d/value",static_cast<int>(m_pin));
    fp = fopen(fileName,"rb");
    if(fp == nullptr)
    {
        DebugPrintf("error\n");
        return -1;
    }
    read_len = fread(file_buffer, 1, 1, fp);
    if(read_len <= 0)
    {
        fclose(fp);
        DebugPrintf("error\n");
        return -1;
    }
    int result;
    if(file_buffer[0] == '0')
    {
        DebugPrintf("read 0\n");
        result = 0;
    }
    else if(file_buffer[0] == '1')
    {
        DebugPrintf("read 1\n");
        result = 1;
    }
    else
    {
        DebugPrintf("error\n");
        result = -1;
    }
    fclose(fp);
    return result;
}

Gpio::~Gpio()
{
    DebugPrintf("Destructors io%d\n",static_cast<int>(m_pin));
    UnexportIo();
}

/********************************************************************\
 *
 * REVISION RECORDS
 *
\*********************************************************************/
/*********************************************************************/
/*
 *
 *
 *
\*********************************************************************/
/*------------------------------The End------------------------------*/

